package com.example.gobang.api;

import com.example.gobang.game.MatchRequest;
import com.example.gobang.game.MatchResponse;
import com.example.gobang.game.Matcher;
import com.example.gobang.game.OnlineUserManager;
import com.example.gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
public class MatchAPI extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        try {
            //websocket 的 session
            //从登陆时获取到user信息
            User user = (User) session.getAttributes().get("user");

            WebSocketSession tmpSession = onlineUserManager.getFromHall(user.getUserId());
            if (tmpSession != null) {
                MatchResponse response = new MatchResponse();
                response.setOk(false);
                response.setReason("无法登录！当前账号已在线");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                session.close();
                return;
            }
            onlineUserManager.enterHall(user.getUserId(), session);
            System.out.println("玩家" + user.getUsername() + "进入游戏大厅");

        } catch (NullPointerException e) {
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("您当前尚未登陆！");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        User user = (User) session.getAttributes().get("user");

        String payload = message.getPayload(); // 此处的 payload 接收前端发过来的信息
        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if (request.getMessage().equals("startMatch")) {
            matcher.add(user);

            response.setOk(true);
            response.setMessage("startMatch");

        } else if (request.getMessage().equals("stopMatch")) {
            matcher.remove(user);

            response.setOk(true);
            response.setMessage("stopMatch");

        } else {

            response.setOk(false);
            response.setReason("非法的匹配请求");
        }

        String jsonString = objectMapper.writeValueAsString(response);
        session.sendMessage(new TextMessage(jsonString));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println("连接错误！");
        try {
            // 玩家下线, 从 OnlineUserManager 中删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromHall(user.getUserId());
            if (tmpSession == session) {
                onlineUserManager.exitHall(user.getUserId());
            }
            // 如果玩家正在匹配中, 而 websocket 连接断开了, 就应该移除匹配队列
            matcher.remove(user);
        } catch (NullPointerException e) {
            System.out.println("[MatchAPI.handleTransportError] 当前用户未登录!");
//            e.printStackTrace();

//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录! 不能进行后续匹配功能!");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("连接断开！");
        try {
            // 玩家下线, 从 OnlineUserManager 中删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromHall(user.getUserId());

            //连接断开，更改大厅在线状态
            if (tmpSession == session) {
                onlineUserManager.exitHall(user.getUserId());
            }

            // 如果玩家正在匹配中, 而 websocket 连接断开了, 就应该移除匹配队列
            matcher.remove(user);
        } catch (NullPointerException e) {
            System.out.println("[MatchAPI.afterConnectionClosed] 当前用户未登录!");
            // e.printStackTrace();

            // 这个代码之前写的草率了!!
            // 不应该在连接关闭之后, 还尝试发送消息给客户端
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录! 不能进行后续匹配功能!");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }
}
